package org.java.cart.service.impl;

import org.java.auth.pojo.UserInfo;
import org.java.common.entity.Cart;
import org.java.cart.feigns.SkuClient;
import org.java.cart.interceptor.CartInterceptor;
import org.java.cart.service.CartService;
import org.java.common.util.JsonUtils;
import org.java.item.entity.Sku;
import org.json.JSONObject;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author WHQ
 * @version 1.0
 * @date 2022-3-13 0013 下午 2:57
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private SkuClient skuClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //定义一个存放在redis中的前缀
    private String keyPrefix ="goShopping:cart:uid:";
    /**
     * 添加购物车的方法
     * cart中，只包含了skuId，num
     * 还缺少userId:从线程变量中直接获取
     * price，title，images:查询商品微服务
     * @param cart
     */
    @Override
    public void addCart(Cart cart) {
        //从线程变量中取得userInfo对象
        UserInfo userInfo = CartInterceptor.getUserInfo();
        //拼接存放在redis中的前缀
        String key=keyPrefix+userInfo.getId();
        //得到商品的数量
        Integer num = cart.getNum();
        //根据键，获得该用户的购物信息
        /**
         * 1.key:标识是哪一个用户的信息
         * 2.字段:skuId
         * 3.商品:Cart对象，对应的json格式的数据
         */
        BoundHashOperations<String, Object, Object> ops = stringRedisTemplate.boundHashOps(key);
        //从cart中取得skuId，判断该商品信息在redis中是否存在，如果存在，取得商品信息数量+1，如果不存在，就需要新增一件商品信息
        Long skuId = cart.getSkuId();
        Boolean flag = ops.hasKey(skuId.toString());
        if (flag){
            //表示该商品已存在redis中
            String json=(String)ops.get(skuId.toString());
            //将json字符串转换为对象
            cart=JsonUtils.parse(json,Cart.class);
            //商品数量进行改变
            cart.setNum(cart.getNum()+num);
        }else {
            //表示商品不在redis中，需要数据库中查询
            Sku sku = skuClient.findById(skuId);
            //设置相关信息
            cart.setImage(sku.getImages());
            cart.setPrice(sku.getPrice());
            cart.setTitle(sku.getTitle());
            cart.setUserId(userInfo.getId());
            cart.setNum(num);
        }
        //序列化对象
        String serializeCartJson = JsonUtils.serialize(cart);
        //将序列化好的数据存放到redis中
        ops.put(skuId.toString(),serializeCartJson);
        System.out.println("存放到数据库成功");
    }

    @Override
    public List<Cart> queryCart() {
        //从拦截器中的获得载荷对象
        UserInfo userInfo = CartInterceptor.getUserInfo();
        //得到用户id
        Long id = userInfo.getId();
        //拼接redis中的key
        String key=keyPrefix+id;
        //从redis中取出数据
        BoundHashOperations<String, Object, Object> ops = stringRedisTemplate.boundHashOps(key);
        //得到值
        List<Object> values = ops.values();
        //将Object转换为cart
        List<Cart> list = values.stream().map(k -> JsonUtils.parse(k.toString(), Cart.class)).collect(Collectors.toList());
        return list;
    }

    @Override
    public void cutNum(Long skuId) {
        //从拦截器中获取载荷对象
        UserInfo userInfo = CartInterceptor.getUserInfo();
        //获得用户id
        Long id = userInfo.getId();
        //拼接成redis中的key
        String key=keyPrefix+id;
        //从redis中取出数据
        BoundHashOperations<String, Object, Object> ops = stringRedisTemplate.boundHashOps(key);
        //得到指定skuId的对象数据
        String json = ops.get(skuId.toString()).toString();
        //将json转换成cart
        Cart cart = JsonUtils.parse(json, Cart.class);
        if (cart==null){
            throw new RuntimeException("商品id错误!");
        }
        //后台二次判断数量是否小于0
        if (cart.getNum()<=0) {
            throw new RuntimeException("商品数量不能小于0!");
        }
        cart.setNum(cart.getNum()-1);
        //重新存到redis中覆盖之前的数据
        ops.put(skuId.toString(),JsonUtils.serialize(cart));
    }

    @Override
    public void addNum(Long skuId) {
        //从拦截器中获取载荷对象
        UserInfo userInfo = CartInterceptor.getUserInfo();
        //获得用户id
        Long id = userInfo.getId();
        //拼接成redis中的key
        String key=keyPrefix+id;
        //从redis中取出数据
        BoundHashOperations<String, Object, Object> ops = stringRedisTemplate.boundHashOps(key);
        //得到指定skuId的对象数据
        String json = ops.get(skuId.toString()).toString();
        //将json转换成cart
        Cart cart = JsonUtils.parse(json, Cart.class);
        if (cart==null){
            throw new RuntimeException("商品id错误!");
        }
        //后台二次判断数量是否小于0
        if (cart.getNum()>10) {
            throw new RuntimeException("商品数量不能大于!");
        }
        cart.setNum(cart.getNum()+1);
        //重新存到redis中覆盖之前的数据
        ops.put(skuId.toString(),JsonUtils.serialize(cart));
    }

    @Override
    public Boolean del(Long skuId) {
        //从拦截器中获取载荷对象
        UserInfo userInfo = CartInterceptor.getUserInfo();
        //获得用户id
        Long id = userInfo.getId();
        //拼接成redis中的key
        String key=keyPrefix+id;
        //从redis中取出数据
        BoundHashOperations<String, Object, Object> ops = stringRedisTemplate.boundHashOps(key);
        //先判断这个要删除的商品id是否存在
        Boolean flag = ops.hasKey(skuId.toString());
        if (flag){
            //存在，直接删除
            Long rows = ops.delete(skuId.toString());
            return rows>0;
        }else {
            return false;
        }
    }
    @Override
    public void batchDel(String[] skuIdList) {
        //从拦截器中获取载荷对象
        UserInfo userInfo = CartInterceptor.getUserInfo();
        //获得用户id
        Long id = userInfo.getId();
        //拼接成redis中的key
        String key=keyPrefix+id;
        //从redis中取出数据
        BoundHashOperations<String, Object, Object> ops = stringRedisTemplate.boundHashOps(key);
        for (String skuId : skuIdList) {
            Boolean flag = ops.hasKey(skuId);
            if (flag){
                //存在可以删除
                ops.delete(skuId);
            }else {
                //不存在，抛出异常
                throw new RuntimeException("商品id不存在!");
            }
        }
    }

    /**
     * 监听订单服务发出的消息
     * 得到创建订单完成以后的skuId数组，进行删除
     * @param json
     */
    @RabbitListener(queues = "shopping_cart_queue")
    public void listenerSkuIds(String json){
        Map<String, String> map = JsonUtils.parseMap(json, String.class, String.class);
        String ids = map.get("skuList");
        //得到用户信息
        String userId = map.get("userId");
        System.out.println(userId);
        //拼接成redis中的key
        String key=keyPrefix+userId;
        //从redis中取出对应key的值
        BoundHashOperations<String, Object, Object> ops = stringRedisTemplate.boundHashOps(key);
        //得到商品数组
        String[] skuList = JsonUtils.parse(ids, String[].class);
        for (String skuId : skuList) {
            ops.delete(skuId);
        }

    }

}
